Fox's Git Mirrors
docs/en/interfaces.md 633735d797cc5f5d48cb2e22e8fd7cd743930daf (633735d7) Text, 17.36 KB
Interfaces
Role
Interfaces move Reticulum packets between the transport layer and a physical or virtual medium. All implementations live in T383838pkg/interfaces and conform to the Interface contract defined in T383838interface.go.
Factory entry point:
T282828
iface, err := interfaces.NewFromConfigWithContext(ctx, name, cfg)
Interface contract
Each interface implements:
• Start and Stop for lifecycle
• Send for outbound data
• ProcessIncoming and ProcessOutgoing for IFAC and framing
• Statistics hooks used by the daemon and control API
Inbound path:
T282828
raw bytes -> ProcessIncoming -> packetCallback -> Transport.HandlePacket
Outbound path:
T282828
Transport.SendPacket -> Send -> ProcessOutgoing -> wire
Supported types
┌───────────────────────────────────────┬─────────────────┬────────────────────────────────────────┐
│ Config type │ Status │ File │
├───────────────────────────────────────┼─────────────────┼────────────────────────────────────────┤
│ UDPInterface │ Complete │ T383838udp.go │
│ TCPClientInterface │ Complete │ T383838tcp.go │
│ TCPServerInterface │ Complete │ T383838tcp.go │
│ AutoInterface │ Complete │ T383838auto.go, T383838auto_rescan.go, T383838auto_roam.go │
│ I2PInterface │ Complete │ T383838i2p.go (SAM in T383838pkg/i2p) │
│ BackboneInterface │ Complete │ T383838backbone.go │
│ BackboneClientInterface │ Complete │ T383838backbone_client.go │
│ PipeInterface │ Complete │ T383838pipe.go │
│ SerialInterface │ Complete │ T383838serial.go │
│ LocalInterface / LocalServerInterface │ Complete │ T383838local.go, sharedinstance │
│ WebSocketInterface │ Go-only │ T383838websocket_native.go, T383838websocket_wasm.go │
│ QUICClientInterface │ Go-only │ T383838quic.go, T383838quic_tls.go │
│ QUICServerInterface │ Go-only │ T383838quic.go, T383838quic_tls.go │
│ WebTransportClientInterface │ Go-only │ T383838webtransport.go │
│ WebTransportServerInterface │ Go-only │ T383838webtransport.go │
│ DNSRendezvousInterface │ Go-only │ T383838dns_rendezvous.go │
│ VSOCKClientInterface │ Go-only (Linux) │ T383838vsock.go │
│ VSOCKServerInterface │ Go-only (Linux) │ T383838vsock.go │
│ HTTPSClientInterface │ Go-only │ T383838https.go │
│ HTTPSServerInterface │ Go-only │ T383838https.go │
│ Modem73Interface │ Complete │ T383838modem73.go │
│ SDRInterface │ Complete │ T383838sdr.go, T383838pkg/sdr │
└───────────────────────────────────────┴─────────────────┴────────────────────────────────────────┘
Not implemented
These interface types have no driver in Reticulum-Go:
• RNodeInterface, RNodeMultiInterface
• KISSInterface, AX25KISSInterface
• WeaveInterface
• Android-specific KISS, RNode, Serial variants
Modem73Interface
KISS TCP data path plus length-prefixed JSON control for a modem73 process.
Defaults: data T383838127.0.0.1:8001, control T383838127.0.0.1:8073, IFAC size 8.
T282828
[[MODEM73]]
type = Modem73Interface
enabled = yes
target_host = 127.0.0.1
target_port = 8001
control_host = 127.0.0.1
control_port = 8073
mtu_overhead = 15
bitrate = 400
auto_fragmentation = yes
short_frames = auto
short_mtu = 170
mode = boundary
DSP stays in the modem73 process. Live: T383838RUN_LIVE_INTEROP=1 with T383838tests/interop/modem73_live_test.go.
Math-backed TNC simulator (no radio): Modem73Simulator in T383838modem73_sim.go with PHY tables from modem73 (T383838CONTROL_PORT.md, robust nrows airtime, OFDM payload/bitrate/duration matrices). Shared Modem73Channel applies SNR and BER/FER models for multi-station tests.
SDRInterface
Owns an SDR front end via pkg/sdr and a Go burst modem over baseband IQ.
Lab / testing disclaimer. This interface is for local mock, simulation, and controlled lab use. It is not a certified radio product and does not grant authority to transmit. Live TX (for example HackRF) can radiate on the tuned frequency. You must follow local license, band, power, and interference rules. Prefer device = mock or the math channel for development. The burst modem is not air-compatible with Modem73 OFDM or RNode. Everyday RF mesh should use purpose-built interfaces when those fit the link.
T282828
[[SDR0]]
type = SDRInterface
enabled = yes
device = mock
frequency = 433000000
sample_rate = 2000000
rx_gain = 20
tx_gain = 10
modem = burst
bitrate = 1200
mode = boundary
Device values: mock (always), rtltcp, rtlsdr (build tag sdrrtlsdr), hackrf (build tag sdrhackrf).
Default builds need no USB libraries. Burst modem is Go-native and is not air-compatible with Modem73 OFDM.
Math-backed RF channel: pkg/sdr/channel.go (FreeSpacePathLossDB, thermal noise, AWGN via Box-Muller, SimDevice). Validated by SNR measurement and FSPL exploratory checks.
Live: T383838RUN_LIVE_SDR=1 with T383838tests/interop/sdr_live_test.go. Optional T383838SDR_DEVICE / T383838SDR_ADDRESS for hardware probes.
SerialInterface
HDLC-framed serial port (MTU 564, baud as bitrate, default IFAC size 8).
Go extensions:
• Chunked reads instead of byte-at-a-time
• Configurable inter-byte frame idle drop (frameidlems, default 100)
• maxreconnecttries and reconnect delay
• Optional RTS/CTS DSR/DTR XON/XOFF keys
• IFAC and receive-only (T383838outgoing = no)
• Live counters (FramesRX/TX, framing errors, reconnects)
• Injectable port opener for tests
T282828
[[Radio Serial]]
type = SerialInterface
enabled = yes
port = /dev/ttyUSB0
speed = 115200
databits = 8
parity = N
stopbits = 1
T383838device = is an alias for the TTY path. Non-numeric T383838port = values are treated as device paths so Python configs load.
Live Python framing interop: T383838RUN_LIVE_INTEROP=1 with T383838tests/interop/serial_live_test.go.
PipeInterface
Bridges Reticulum to any external program over stdin/stdout using HDLC framing.
Configuration:
• command (required): program and arguments, split like Python shlex
• respawn_delay (optional): seconds before respawning after subprocess exit (default 5)
External interface plugins
Python loads T383838.py modules from T383838{config_dir}/interfaces/. Reticulum-Go keeps the same discovery path but uses process isolation and in-process factories instead of executing Python:
1. T383838interfaces.RegisterExternalFactory(typeName, factory) for embedders
2. T383838{config_dir}/interfaces/{Type}.json (or T383838.manifest) with driver and command (pipe)
3. Executable T383838{config_dir}/interfaces/{Type} used as a PipeInterface command
Example manifest:
T282828
{"driver": "pipe", "command": "/usr/local/bin/my-rns-iface", "respawn_delay": 5}
Config:
T282828
[[Custom Radio]]
type = MyRadioIface
enabled = yes
LocalInterface
Local shared-instance access uses HDLC over TCP (T383838127.0.0.1:port) or abstract Unix (T383838@rns/<name>).
Two configuration paths:
1. Automatic (Python-compatible): T383838share_instance = yes in T383838[reticulum] via T383838pkg/sharedinstance
2. Explicit interface block: T383838type = LocalInterface or T383838type = LocalServerInterface in T383838[[...]]
Local clients set ConnectedToSharedInstance and skip path-request ingress limiting, matching Python behavior.
UDPInterface
Connects to a configured peer over UDP.
Requirements:
• Explicit targetaddress or targethost (same policy as Python forward_ip)
• Open binds do not adopt the source address of the first inbound packet
Optional reconnect when T383838max_reconnect_tries > 0 is a Go extension. Python does not reconnect UDP by default.
TCP client and server
TCP uses HDLC framing with a maximum frame size cap (maxHDLC in T383838tcp.go). Client interfaces support:
• Keepalives
• Reconnect via T383838reconnect.go
• Tunnel re-synthesis on reconnect (SetTunnelSynth / onConnected)
• Optional I2P tunneling (i2p_tunneled)
Server interfaces accept inbound connections and apply IFAC on each session.
AutoInterface
AutoInterface discovers peers on a local link using IPv6 link-local multicast.
Features:
• Peer aging and timeout
• Configurable discovery and data ports
• NIC binding via interface key
• Rescan when T383838watch_interfaces = yes (T383838auto_rescan.go)
• Listener replacement on Wi-Fi roam (T383838auto_roam.go, aligned with Python 1.3.5)
Interface modes
Modes match Python RNS wire values (full 0x01 through internal 0x07). Set with mode or interface_mode on an interface block.
┌───────────────────────────────┬──────────────────────────────────────────────────────────────┐
│ Mode │ Effect (summary) │
├───────────────────────────────┼──────────────────────────────────────────────────────────────┤
│ full │ Default. Normal announce and path behavior │
│ access_point │ Does not rebroadcast announces │
│ gateway / roaming / internal │ Participate in unknown-path discovery (T383838DISCOVER_PATHS_FOR) │
│ boundary / roaming / internal │ Extra announce forward filters vs next-hop mode (RNS 1.3.6+) │
└───────────────────────────────┴──────────────────────────────────────────────────────────────┘
T383838recursive_prs = yes forces unknown-path discovery on any mode. T383838announces_from_internal = no blocks rebroadcast of announces learned via an internal-mode next hop.
I2PInterface
Uses I2P SAM (T383838pkg/i2p) for inbound and outbound streams.
Outbound peers dial with a direct SAM T383838STREAM CONNECT (no local TCP proxy hop). The peer is marked online only after that connect succeeds. Reconnect closes the prior SAM session and opens a new one. Stream sessions use T383838i2cp.leaseSetEncType=6,4 by default.
Configuration keys: samaddress, peers, connectable, i2ptunneled.
Live SAM tests require T383838RUN_LIVE_I2P=1 and a running SAM bridge (T383838I2P_SAM_ADDRESS, default T383838127.0.0.1:7656). Directory peer smoke fetches online I2P hosts from T383838directory.rns.recipes at runtime (override with T383838I2P_DIRECTORY_URL or T383838INTEROP_DIRECTORY_URL). Do not hardcode public b32 addresses in the tree.
Go and Python interop lives in T383838tests/interop/i2p_live_test.go (T383838RUN_LIVE_INTEROP=1 plus a reachable SAM).
Backbone
Backbone interfaces multiplex many TCP streams through T383838pkg/backbone hubs. Select poller backend with backbone_io in T383838[reticulum]:
┌──────────┬────────────────────────┐
│ Value │ Platform │
├──────────┼────────────────────────┤
│ auto │ Best available │
│ epoll │ Linux │
│ kqueue │ BSD, macOS │
│ io_uring │ Linux (when available) │
│ go │ Portable fallback │
└──────────┴────────────────────────┘
WebSocketInterface
Go-only transport for browser WASM clients. Native builds use T383838websocket_native.go. WASM builds use T383838websocket_wasm.go.
QUICClientInterface / QUICServerInterface
Go-only QUIC transport (not available on WASM). HDLC frames ride one bidirectional QUIC stream per connection, matching the TCP interface framing model.
TLS follows a Yggdrasil-style mesh model:
• Ephemeral self-signed ECDSA P-256 certificates by default
• X.509 CA verification is skipped (InsecureSkipVerify)
• Optional peer_key pins the remote leaf SPKI SHA-256 (hex)
• Optional certfile / keyfile supply persistent PEM material
• Optional sni sets the client TLS ServerName
• ALPN is fixed to rns
• IFAC (network_name / passphrase) still applies above QUIC
T282828
[[QUIC Hub]]
type = QUICServerInterface
enabled = yes
listen_ip = 0.0.0.0
listen_port = 4242
[[QUIC Uplink]]
type = QUICClientInterface
enabled = yes
target_host = hub.example.com
target_port = 4242
peer_key = aabbccdd...
max_reconnect_tries = -1
Client reconnect uses T383838reconnect.go like TCP. Server fan-out writes to all accepted sessions. Live Go-Go tests: T383838RUN_LIVE_INTEROP=1 with T383838tests/interop/quic_live_test.go.
WebTransportClientInterface / WebTransportServerInterface
Go-only HTTP/3 WebTransport transport (not on WASM). Prefer datagrams for RNS packets. Optional HDLC stream mode matches QUIC.
• Default path T383838/rns
• T383838transport_mode = datagram (default), stream, or dual
• Application protocol rns
• Same TLS options as QUIC (certfile, keyfile, peer_key, sni)
• IFAC and reconnect supported
T282828
[[WT Hub]]
type = WebTransportServerInterface
enabled = yes
listen_ip = 0.0.0.0
listen_port = 4433
path = /rns
transport_mode = datagram
[[WT Client]]
type = WebTransportClientInterface
enabled = yes
target_host = hub.example.com
target_port = 4433
path = /rns
transport_mode = datagram
peer_key = aabbccdd...
DNSRendezvousInterface
Go-only rendezvous underlay (not a DNS tunnel). Looks up DNS TXT for peer endpoints, then carries RNS packets over UDP to the discovered address.
TXT forms accepted:
• T383838rns=udp://1.2.3.4:4242
• T383838rns proto=udp host=1.2.3.4 port=4242
Hosts must be a parseable IP or DNS name without whitespace. Only udp and tcp schemes are accepted (udp is used by this underlay). Invalid TXT records are ignored.
T282828
[[DNS Peer]]
type = DNSRendezvousInterface
enabled = yes
domain = peers.example.com
listen_ip = 0.0.0.0
listen_port = 0
resolve_interval = 60
resolve_interval is seconds between re-queries (default 60). Publish the TXT at domain (or a name your resolver returns for that query). Live Go-Go: T383838RUN_LIVE_INTEROP=1 with T383838tests/interop/dns_rendezvous_live_test.go.
VSOCKClientInterface / VSOCKServerInterface
Go-only Linux T383838AF_VSOCK transport with HDLC framing (same pattern as TCP). Useful for host-guest and same-host Local CID paths.
T282828
[[VSOCK Hub]]
type = VSOCKServerInterface
enabled = yes
port = 4242
[[VSOCK Client]]
type = VSOCKClientInterface
enabled = yes
context_id = 3
port = 4242
max_reconnect_tries = -1
context_id / cid is the peer CID (1 is Local on Linux). Not available on non-Linux or WASM. Live Local CID: T383838RUN_LIVE_INTEROP=1 with T383838tests/interop/vsock_live_test.go.
HTTPSClientInterface / HTTPSServerInterface
Go-only TLS long-poll packet underlay for restrictive networks where only HTTPS egress works. Not WebTransport or HTTP/3.
• Default path T383838/rns
• Client T383838POST {path}/send and long-poll T383838GET {path}/poll
• Peer id header T383838X-RNS-Peer
• Same TLS options as QUIC (certfile, keyfile, peer_key, sni)
• longpollsec default 25
T282828
[[HTTPS Hub]]
type = HTTPSServerInterface
enabled = yes
listen_ip = 0.0.0.0
listen_port = 8443
path = /rns
cert_file = /path/to/cert.pem
key_file = /path/to/key.pem
[[HTTPS Client]]
type = HTTPSClientInterface
enabled = yes
target_host = hub.example.com
target_port = 8443
path = /rns
long_poll_sec = 25
peer_key = aabbccdd...
Live Go-Go: T383838RUN_LIVE_INTEROP=1 with T383838tests/interop/https_live_test.go.
Interface Access Code (IFAC)
When network_name and passphrase are set on an interface, frames are masked on egress and verified on ingress.
Policy:
• Wrong or missing IFAC on a configured interface results in silent drop on ingress
• Applied on UDP, TCP, Auto, and other supported types via T383838pkg/common.ApplyIFACInbound and ApplyIFACOutbound
Details: Cryptography.
Reconnect behavior
┌───────────────────────────────────────────────────────────┬────────────────────────────────┬─────┐
│ Aspect │ Python RNS │ Re… │
├───────────────────────────────────────────────────────────┼────────────────────────────────┼─────┤
│ TCP / backbone / QUIC / WebTransport / HTTPS / VSOCK cli… │ Yes for TCP/backbone, 5 s wait │ Ye… │
│ Serial │ Yes, 5 s wait │ Ye… │
│ I2P │ Yes, 15 s wait │ Ye… │
│ UDP / DNS rendezvous │ No │ UD… │
│ Default max tries │ Unlimited (None) │ Un… │
│ After exhaustion │ Teardown │ Te… │
└───────────────────────────────────────────────────────────┴────────────────────────────────┴─────┘
ConnectivityNotifier hooks allow embedders to observe reconnect state (Go-only).
Hot reload
T383838node.ReloadInterfaces swaps interface blocks without restarting the process. On Unix, T383838SIGHUP triggers reload in the daemon.
On unregister, transport scrubs paths, discovery state, announce bookkeeping, relay rows, and link-table entries for the removed interface.
Equality checks in T383838pkg/node/reload.go cover type, addresses, I2P settings, IFAC, Auto ports, MTU, bitrate, prefer_ipv6, announce-rate, ingress/egress control, mode, and outgoing.
Tests: T383838interface_lifecycle_test.go, T383838reload_e2e_test.go.
Rate and ingress settings
Per-interface keys announcecap, T383838announce_rate_*, ingresscontrol, and T383838ic_* feed T383838pkg/rate limiters consumed by transport ingress handlers.
Operational notes
MTU. Default Reticulum packet MTU is 500 bytes (T383838pkg/packet.MTU). Interface mtu should be consistent with the physical path. Stream underlays still read 64 KiB from the socket so many HDLC frames can arrive in one Read. UDP and DNS rendezvous stay datagram-sized.
IPv6. prefer_ipv6 affects TCP and Auto binding and discovery.
Panic on error. T383838panic_on_interface_error = yes can crash the daemon on fatal interface errors. Default is no.
Testing
┌───────────────────────────┬──────────────────────────────────────────────────────────────────────┐
│ Test │ Env / command │
├───────────────────────────┼──────────────────────────────────────────────────────────────────────┤
│ IFAC live │ T383838RUN_LIVE_INTEROP=1, T383838tests/interop/ifac_live_test.go │
│ Pipe live │ T383838RUN_LIVE_INTEROP=1, T383838tests/interop/pipe_live_test.go │
│ Serial live │ T383838RUN_LIVE_INTEROP=1, T383838tests/interop/serial_live_test.go │
│ DNS rendezvous live │ T383838RUN_LIVE_INTEROP=1, T383838tests/interop/dns_rendezvous_live_test.go │
│ VSOCK live │ T383838RUN_LIVE_INTEROP=1, T383838tests/interop/vsock_live_test.go (Linux) │
│ HTTPS live │ T383838RUN_LIVE_INTEROP=1, T383838tests/interop/https_live_test.go │
│ QUIC / WebTransport live │ T383838RUN_LIVE_INTEROP=1, T383838tests/interop/quic_live_test.go │
│ Shared RPC live │ T383838RUN_LIVE_INTEROP=1, T383838tests/interop/shared_rpc_live_test.go │
│ Auto live │ T383838tests/interop/auto_live_test.go │
│ Backbone live │ T383838tests/interop/backbone_live_test.go │
│ I2P live │ T383838RUN_LIVE_I2P=1 (directory peers fetched at runtime) │
│ I2P Go and Python interop │ T383838RUN_LIVE_INTEROP=1 plus reachable SAM, T383838tests/interop/i2p_live_test.… │
│ Race (Stop vs Send) │ T383838go test -race ./pkg/interfaces/ -run Race plus DNS/VSOCK/HTTPS/I2P … │
│ Goroutine leak │ T383838go test ./pkg/interfaces/ -run NoGoroutineLeak │
│ Fuzz (examples) │ T383838go test ./pkg/interfaces/ -run '^$' -fuzz=FuzzParseRNSTXT -fuzztime… │
└───────────────────────────┴──────────────────────────────────────────────────────────────────────┘
Fuzz targets cover TXT parsing (FuzzParseRNSTXT), HTTPS path/long-poll normalization, WebTransport path/mode, VSOCK CID and HDLC decode, Serial HDLC, peer-key pins, and I2P SAM message or destination resolve (T383838pkg/i2p).
Related documents
• Configuration for interface block keys
• Transport for registration and forwarding
• Compatibility for Python interface matrix
Served by rngit 1.5.2 - Generated in 0.03s